﻿using System;

using imaginecup.objectManager;
using imaginecup.information;
using Imaginecup.util.input;
using Microsoft.Xna.Framework.Input.Touch;
using Imaginecup.util.compute;
using Microsoft.Xna.Framework;
using Imaginecup.util.collision;
using imaginecup.util;
using Imaginecup.gameState.malaria.componentInit;
using Imaginecup.gameState.malaria.component.children;
using Imaginecup.util;
using Microsoft.Xna.Framework.Input;
using Imaginecup.sprite;
using Imaginecup.gameState.malaria.manager;
using Imaginecup.gameState.malaria.component.entity;
using System.Collections.Generic;
using Imaginecup.gameState.malaria.component.util;
using Imaginecup.util.script.malaria;
using Imaginecup.sprite.animation;

namespace Imaginecup.gameState.malaria.component.malaria
{
   
    public class CmpMalaria:BaseEntityComponent , ICmpMalaria , IReverseInfoClass
    {
        private ICmpChar m_DestChildren = null;
        private bool m_bStop;
        private int m_Velocity ; //속력        
        private float m_Demage;

        private int m_HP;
        private bool m_bReverse = false;
        private AnimationIndexMan m_AnimationMan;

        public override void Release()
        {
            m_DestChildren = null;
        }


        public CmpMalaria(GObjectID a_GID, ObjectManager objMan)
            : base(a_GID, objMan, ComponentTypeID.CID_MALARIA_ENTITY)
        {
            m_Demage = 10;
            
            m_bStop = false;
            m_HP = 10;
        }
        public void SetVelocity(double velocity)
        {
            m_Velocity = (int)velocity;
        }


        public override void Init()
        {
            m_AnimationMan = new AnimationIndexMan();

            m_AnimationMan.SetDelay( 0.05 );
            m_AnimationMan.SetIndex(Vector2.Zero , 6);
            m_AnimationMan.StartAnimation();

            AnimationSprite animation = new AnimationSprite( m_AnimationMan , this );
            animation.SetTextureName("Malaria");

            ICmpRender render = new CmpDefaultRender(m_ObjectID, m_ObjectMan, animation, ComponentTypeID.CID_RENDER_MALARIA);
            m_ObjectMan.AddComponent(render);

            m_Velocity = RandomUtil.rand.Next(20, 45);

            base.Init();
        }

        public override void Update(GameTime gameTime)
        {
            if (m_bStop) return ;

            UpdateMararia(gameTime);
            GMessage Msg = new GMessage();
            Msg.m_Data = this;
            Msg.m_FromID = m_ObjectID;
            Msg.m_Type = MessageTypeID.MT_CHANGE_MALARIAPOSITION;

            m_ObjectMan.BroadCastMessage(Msg);

            m_AnimationMan.Update(gameTime);

            base.Update(gameTime);
        }
        public override EMessageResult HandleMessage(GMessage a_Msg)
        {
            if (a_Msg.m_Type.MessageTypeID == MessageTypeID.MT_CHECK_INPUT.MessageTypeID)
            {

            }

            else if (a_Msg.m_Type.MessageTypeID == MessageTypeID.MT_CHECK_ATTACK.MessageTypeID)
            {
                AttackInfo attackInfo = (AttackInfo)a_Msg.m_Data;
                IMouseInputHandler mouseInput = MouseInputHandler.GetInputHandler();

                switch( attackInfo.attackID )
                {
                    case AttackID.ATTACK_HAND:
                        if (Collision.CollisionByPoint(m_Info, mouseInput.Position))
                        {
                            //눌려졌으면 눌려진 객체를 등록.
                            List<ICmpMalaria> list = (List<ICmpMalaria>)attackInfo.extraData;
                            list.Add(this);
                        }
                        break;
                    case AttackID.ATTACK_SLICE:
                        SliceInfo sliceInfo = (SliceInfo)attackInfo.extraData;

                        if( Collision.CollisionLineWithRect(sliceInfo.prevPosition , sliceInfo.lastPosition , m_Info.mPosition , m_Info.mSize) )
                        {
                            AddDemage(0);
                        }
                        break;
                    case AttackID.ATTACK_MOVE:
                        if (Collision.CollisionByPoint(m_Info, mouseInput.Position))
                        {
                            //눌려졌으면 눌려진 객체를 등록.
                            List<ICmpMalaria> list = (List<ICmpMalaria>)attackInfo.extraData;
                            list.Add(this);
                        }
                        break;
                }

            }

            else if (a_Msg.m_Type.MessageTypeID == MessageTypeID.MT_CHANGE_CHILDRENPOSITION.MessageTypeID)
                CompareChildrenPos((ICmpChar)a_Msg.m_Data);

            else if (a_Msg.m_Type.MessageTypeID == MessageTypeID.MT_CHILD_DIE.MessageTypeID)
            {
                //죽었다. 다른 목표를 찾으면 된다.
                if (m_DestChildren != null && m_DestChildren.GetObjectID() == a_Msg.m_FromID)
                {
                    m_DestChildren = null;
                }
            }

            return base.HandleMessage(a_Msg);
        }

        public bool IsMoveAble()
        {
            return !m_bStop;
        }

        public void StopMove()
        {
            m_bStop = true;
        }

        public void ReleaseStop()
        {
            m_bStop = false;
        }

        public void AddDemage(float demage)
        {
            m_HP--;

            if (m_HP <= 0)
            {
                GMessage msg = new GMessage(MessageTypeID.MT_MALARIA_DIE, m_ObjectID);
                m_ObjectMan.BroadCastMessage(msg);

                m_ObjectMan.DestroyObject(m_ObjectID);
                GameResourceMan.GetResourceMan().AddMoney(1);// 돈 1원 추가.
            }
        }

        private void CompareChildrenPos(ICmpChar cmpChildrenEntity)
        {
            if (m_DestChildren == null)
                m_DestChildren = cmpChildrenEntity;

            EntityInfo CurrentChildEntityInfo = (EntityInfo)m_DestChildren.GetEntityInfo();
            EntityInfo CmpEntityInfo = (EntityInfo)cmpChildrenEntity.GetEntityInfo();

            
            // 현재 목표물보다 가까우면 목표물 변경
            if (VectorCompute.IsShortestThan(m_Info.mPosition, CurrentChildEntityInfo.mPosition, CmpEntityInfo.mPosition) == false)
                m_DestChildren = cmpChildrenEntity;

        }

        private void UpdateMararia(GameTime gameTime)
        {
            
            //목표물이 있다면 일정 범위 내에 있으면 데미지주기 , 일정 범위 없으면 이동
            if( m_DestChildren != null )
            {
                EntityInfo destInfo = (EntityInfo)m_DestChildren.GetEntityInfo();

                if( Collision.CollisionByRect(m_Info.mPosition , m_Info.mSize , destInfo.mPosition , destInfo.mSize))
                {
                    m_DestChildren.AddDemage(m_Demage * (float)gameTime.ElapsedGameTime.TotalSeconds);
                }

                else
                {
                    MoveMalaria(destInfo, gameTime);
                }
             }
        }

        private void MoveMalaria(EntityInfo destInfo, GameTime gameTime)
        {
             Vector2 direction = Vector2.Subtract(destInfo.mPosition, m_Info.mPosition);
             direction.Normalize();
            
             MalariaState state = MalariaState.GetMalariaState();

             Vector2 prevPosition = m_Info.mPosition;

             m_Info.mPosition.X += direction.X * m_Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
             if (m_Info.mPosition.X > state.GetMainScreenSize().X - m_Info.mSize.X)
             {
                 m_Info.mPosition.X = state.GetMainScreenSize().X - m_Info.mSize.X;
             }

             m_Info.mPosition.Y += direction.Y * m_Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
            if( m_Info.mPosition.Y > state.GetMainScreenSize().Y - m_Info.mSize.Y)
            {
                m_Info.mPosition.Y = state.GetMainScreenSize().Y - m_Info.mSize.Y;
            }


            if (prevPosition.X > m_Info.mPosition.X)
            {
                m_bReverse = true;
            }
            else
                m_bReverse = false;

        }


        public bool GetReverseInfo()
        {
            return m_bReverse;
        }
    }
}
